using System;
using System.Collections;
using System.Collections.Generic;

namespace LightCAD.Three
{
    public class OrthographicCamera : Camera
    {
        #region Properties

        public View view;
        public double left;
        public double right;
        public double top;
        public double bottom;
        //public double near;
        //public double far;

        #endregion

        #region constructor
        public OrthographicCamera(double left = -1, double right = 1, double top = 1, double bottom = -1, double near = 0.1, double far = 2000)
        {
            this.type = "OrthographicCamera";
            this.zoom = 1;
            this.view = null;
            this.left = left;
            this.right = right;
            this.top = top;
            this.bottom = bottom;
            this.near = near;
            this.far = far;
            this.updateProjectionMatrix();
        }
        #endregion

        #region methods
        public override Camera copy(Camera source, bool recursive)
        {
            return copy(source as OrthographicCamera, recursive);
        }
        public OrthographicCamera copy(OrthographicCamera source, bool recursive)
        {
            base.copy(source, recursive);
            this.left = source.left;
            this.right = source.right;
            this.top = source.top;
            this.bottom = source.bottom;
            this.near = source.near;
            this.far = source.far;
            this.zoom = source.zoom;
            this.view = source.view?.clone();
            return this;
        }
        public override Camera clone()
        {
            return (new OrthographicCamera()).copy(this, true);
        }
        public void setViewOffset(double fullWidth, double fullHeight, double x, double y, double width, double height)
        {
            if (this.view == null)
            {
                this.view = new View();
            }
            this.view.enabled = true;
            this.view.fullWidth = fullWidth;
            this.view.fullHeight = fullHeight;
            this.view.offsetX = x;
            this.view.offsetY = y;
            this.view.width = width;
            this.view.height = height;
            this.updateProjectionMatrix();
        }
        public void clearViewOffset()
        {
            if (this.view != null)
            {
                this.view.enabled = false;
            }
            this.updateProjectionMatrix();
        }

        public override void updateProjectionMatrix()
        {
            var dx = (this.right - this.left) / (2 * this.zoom);
            var dy = (this.top - this.bottom) / (2 * this.zoom);
            var cx = (this.right + this.left) / 2;
            var cy = (this.top + this.bottom) / 2;
            var left = cx - dx;
            var right = cx + dx;
            var top = cy + dy;
            var bottom = cy - dy;
            if (this.view != null && this.view.enabled)
            {
                var scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom;
                var scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
                left += scaleW * this.view.offsetX;
                right = left + scaleW * this.view.width;
                top -= scaleH * this.view.offsetY;
                bottom = top - scaleH * this.view.height;
            }
            this.projectionMatrix.MakeOrthographic(left, right, top, bottom, this.near, this.far);
            this.projectionMatrixInverse.Copy(this.projectionMatrix).Invert();
        }
        #endregion
    }
}
